package com.lill.support.aspect;

import java.util.Map;

import com.lill.common.system.exception.TokenException;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import com.lill.auth2.util.OnceToken;
import com.lill.support.annotation.AuthTokenOnce;
import com.lill.system.constant.SystemConstant;
import com.lill.system.model.SysUserLoginAppEntity;
import com.lill.system.service.ICommonRedisService;

@Component
public class HandlerTokenOnceResolver implements HandlerMethodArgumentResolver {
	
	private final static Logger log = LoggerFactory.getLogger(HandlerTokenOnceResolver.class);
	
	@Autowired
	private ICommonRedisService commonRedisService;
	
	public boolean supportsParameter(MethodParameter parameter) {
		return parameter.hasMethodAnnotation(AuthTokenOnce.class);
	}

	public Object resolveArgument(MethodParameter parameter,ModelAndViewContainer mavContainer, NativeWebRequest webRequest,WebDataBinderFactory binderFactory) throws Exception {
		SysUserLoginAppEntity authBean=null;
		String userId=null;
		String authToken=webRequest.getHeader("Authorization");
		if(StringUtils.isEmpty(authToken)){
			authToken=webRequest.getParameter("xcjtoken");
		}

		log.info("xcjtoken:"+authToken);

		if(StringUtils.isNotEmpty(authToken)){
			Map<String, Object> loginUserMap=commonRedisService.getMapValueByKey(SystemConstant.APP_TOKEN+authToken);
			if(null!=loginUserMap&&!loginUserMap.isEmpty()
					&&loginUserMap.containsKey("token")&&StringUtils.isNotEmpty(loginUserMap.get("token").toString())
					&&authToken.equals(DigestUtils.md5Hex(loginUserMap.get("token").toString()))){
				userId=OnceToken.decryptToken(loginUserMap.get("token").toString());
			}else{
				throw new TokenException("token is error!");
			}
		}else{
			throw new TokenException("token is error!");
		}
		
		if(StringUtils.isNotEmpty(userId)){
			Map<String, Object> loginUserMap=commonRedisService.getMapValueByKey(SystemConstant.APP_TOKEN+authToken);
			if(null!=loginUserMap&&!loginUserMap.isEmpty()&&userId.equals(loginUserMap.get("id").toString())){
				authBean=new SysUserLoginAppEntity();
				BeanUtils.populate(authBean, loginUserMap);
			}else{
				throw new TokenException("token is error!");
			}
		}else{
			throw new TokenException("token verify failure");
		}
		return authBean;
	}
}
